define(function (require) {
    var _ = require('underscore');
    var Backbone = require('backbone');
    var PageView = require('./pages/PageView');
    var $ = require('jquery');
    //
    // app: app model (from app.js)
    var Application = function (model, options) {
        this.model = model;
        this.options = options;
        this.initialize.apply(this, arguments);
    };
    _.extend(Application.prototype, Backbone.Events, {

        initialize: function () {
            this.pages = [];
            this.pagesClass = [];
            this.cache = [];
            this.currentPage = null;
            var _this = this;
            var req = require.context("./pages", true, /^(.*\.(json$))[^.]*$/igm);
            req.keys().forEach(function (key) {
                _this.pages.push(req(key));
            });
        },
        _require: function (path) {
            return require(path);
        },
        launch: function () {
            //console.log(this.pages);
            //this._initCollections();
            //var entryPage = this.getPageId().split('#');

            this.pageContainer = $('<div class="page-group"></div>');
            //var p=this.createPage(window.app.defaultPage);
            //this.pagesClass.push(p);
            //this.currentPage=p;
            this.pageContainer.appendTo(window.document.body);
            //this.currentPage.onRender&&this.currentPage.onRender();
            this._initRouter();
        },

        createPage: function (name) {
            var c = './pages/' + name + ".json";
            var config = this._require(c);
            var PageClass = this._require("./pages/" + config.type + ".js");
            var p = new PageClass(config, this);
            p._id = config.id;
            p.render().$el.appendTo(this.pageContainer);
            return p;
        },
        _initRouter: function () {
            var Router = Backbone.Router.extend({
                routes: {
                    "*path.*(?*queryString)": "any"
                }
            });
            var router = new Router();
            this.listenTo(router, 'route:any', this.route);
            // launch history
            var pathname = window.location.pathname;
            var rootPath = Backbone.history.decodeFragment(pathname); //.substr(0, pathname.lastIndexOf('/'));
            Backbone.history.start({
                pushState: false,
                root: rootPath
            });

            console.log("start history with root: [%s]", rootPath);
        },
        hasPage: function (path) {
            var pageConfig = null;
            this.pages.forEach(function (page, index) {
                if (page.id == path) {
                    pageConfig = page;
                }
            });
            return pageConfig;
        },
        _animateElement: function ($from, $to, direction) {
            // todo: 可考虑如果入参不指定，那么尝试读取 $to 的属性，再没有再使用默认的
            // 考虑读取点击的链接上指定的方向
            if (typeof direction === 'undefined') {
                direction = "rightToLeft";
            }

            var animPageClasses = [
                'page-from-center-to-left',
                'page-from-center-to-right',
                'page-from-right-to-center',
                'page-from-left-to-center'].join(' ');

            var classForFrom, classForTo;
            switch (direction) {
                case "rightToLeft":
                    classForFrom = 'page-from-center-to-left';
                    classForTo = 'page-from-right-to-center';
                    break;
                case "leftToRight":
                    classForFrom = 'page-from-center-to-right';
                    classForTo = 'page-from-left-to-center';
                    break;
                default:
                    classForFrom = 'page-from-center-to-left';
                    classForTo = 'page-from-right-to-center';
                    break;
            }

            $from.removeClass(animPageClasses).addClass(classForFrom);
            $to.removeClass(animPageClasses).addClass(classForTo);

            $from.on("webkitAnimationEnd", function () {
                $from.removeClass(animPageClasses);
                $from.removeClass(classForFrom);
                $from.removeClass(classForTo);
                $from.css({display: 'none'});
            });
            $to.on("webkitAnimationEnd", function () {
                $to.removeClass(animPageClasses);
                $to.removeClass(classForTo);
                $to.removeClass(classForFrom);
                $to.css({display: 'block'});
            });
        },
        unparam: function (str, params) {
            if (!str) return;
            params = params || {};
            str.replace(/\/$/, '').replace(/([^?=&]+)=([^&#]*)/g, function (m, key, value) {
                params[key] = decodeURIComponent(value);
            });

            return params;
        },
        // 新建删除view功能
        removePage: function (path) {
            var _this = this;
            if (!path) return;
            _this.pagesClass.forEach(function (value, key) {
                if (value._parent && value._parent._id == path) {
                    value._parent = '';
                }
            });
            _this.cache.forEach(function (value, key) {
                if (value._id == path) {
                    _this.cache.splice(key, 1);
                }
            });
        },
        route: function (path, queryString) {
            path && (path = _.first(path.split('/')));
            !path && !this.currentPage && (path = window.app.defaultPage);
            !path && this.currentPage && this.hasPage(window.app.defaultPage) && (path = window.app.defaultPage);
            !path && this.currentPage && this.currentPage._parent && (path = this.currentPage._parent.id);
            if ((path && this.hasPage(path))) {

                var lastPage = this.pagesClass[this.pagesClass.length - 1];
                if (lastPage && lastPage._parent && path == lastPage._parent.id) {
                    //返回
                    this._animateElement(this.currentPage.$el, lastPage._parent.$el, 'leftToRight');
                    this.currentPage = lastPage._parent;
                    this.currentPage.$el.css({'display': 'block'});
                    lastPage._parent = null;
                    this.pagesClass.pop();
                    this.currentPage.onResume && this.currentPage.onResume(this.unparam(queryString));
                } else {
                    //新页面
                    var nPage = '';
                    this.cache.forEach(function (it) {
                        if (path == it._id) {
                            nPage = it;
                        }
                    });
                    if (nPage == '') {
                        nPage = this.createPage(path);
                        this.currentPage && this._animateElement(this.currentPage.$el, nPage.$el, 'rightToLeft');
                        nPage._parent = this.currentPage;
                        this.pagesClass.push(nPage);
                        this.cache.push(nPage);
                        this.currentPage = nPage;
                        this.currentPage.onRender && this.currentPage.onRender(this.unparam(queryString));
                    } else {
                        nPage.$el.css({display: 'block'});
                        this._animateElement(this.currentPage.$el, nPage.$el, 'rightToLeft');
                        nPage._parent = this.currentPage;
                        this.pagesClass.push(nPage);
                        this.currentPage = nPage;
                        this.currentPage.onResume && this.currentPage.onResume(this.unparam(queryString));
                    }
                }
            }
        },
    });
    Application.extend = Backbone.Model.extend;
    return Application;
});
